<template>
	<view class="c2bCanvas">
		<view class="uni-margin-wrap">
			<view class="img_box">
				<swiper :circular="circular" :current="currentIndex" :autoplay="swiperAutoplay" interval="4000"
					duration="500" :indicator-dots="false" indicator-active-color="rgba(0, 0, 0, 0)"
					indicator-color="rgba(0, 0, 0, 0)" class="swiper_box" @change="swiperChange">
					<block v-for="(swiperItem, swiperIndex) in previewImg" :key="swiperIndex">
						<block v-if="swiperIndex != 2">
							<swiper-item>
								<image :src="swiperItem" :data-src="swiperItem" class="slide-image" mode="widthFix" />
							</swiper-item>
						</block>
					</block>
				</swiper>
			</view>
			<view class="swiper-dots" v-if="previewImg && previewImg.length > 1">
				<block v-for="(swiperItem, swiperIndex) in previewImg" :key="swiperIndex">
					<block v-if="swiperIndex != 2">
						<view class="swiper-dots-item">
							<image :src="swiperIndex == currentIndex ? swiperDotsActImg : swiperDotsAct
								" style="width: 100%; height: 100%; position: absolute; top: 0" />
						</view>
					</block>
				</block>
			</view>
		</view>
		<view class="img-container">
			<canvas class="goodsLettering-canvas" canvas-id="canvas" id="canvas" type="2d"></canvas>
		</view>
	</view>
</template>

<script>
import ZHText from "./CN-unicode.json";
import ENText from "./EN-unicode.json";
import ICONfONT from "./ICON-unicode.json";
export default {
	props: {
		previewImg: {
			type: Array,
			default: [],
		},
	},
	data() {
		return {
			ctx: null,
			canvas: null,
			canvasStyle: null,
			swiperAutoplay: true,
			circular: true,
			offCtx: null, //离屏实力
			offCanvas: null, //离屏实力
			dpr: 1,
			icon1: "",
			icon2: "",
			icon3: "",
			icon4: "",
			iconUrl: {
				icon1:
					"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/c2b/draw_Icon1.png",
				icon2:
					"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/c2b/draw_Ico2.png",
				icon3:
					"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/c2b/draw_Icon4.png",
				icon4:
					"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/c2b/draw_Icon3.png",
			},
			backImg: "",
			isIos: true,
			swiperDotsActImg:
				"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/pdp/dot2.png",
			swiperDotsAct:
				"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/pdp/dot1.png",
			swiperChangeTimeStamp: new Date().getTime(),
			currentIndex: 0,
			canvasImg: "",
			canvasImg1: "",
			url1: "",
			textBgUrl:
				"https://100000063-1252208446.file.myqcloud.com/images/macallan-remvp/c2b/text-bg-imgs1.png",
			textBg: "",
			textColorImgs: "",
			fontSizePt: 92,
			fontCHwidth: 1000,
			disVal: false,
			previewSwiperImg: "",
		};
	},
	destroyCanvas() {
		try {
			this.canvas.destroy()
			this.offCanvas.destroy()
		} catch (error) {
			console.log(error, 'onUnload')
		}
	},
	methods: {
		async getSwiperImg(preview = [], preview1 = []) {
			// 离屏canvas小图位置
			try {
				const drawW = (this.offCtx.canvas.width / 16).toFixed(2);
				const drawh = (this.offCtx.canvas.height / 16).toFixed(2);
				const transX = (this.canvasStyle.width - drawW) / 2;
				const transY = ((this.canvasStyle.height - drawh) / 2) * 1.7;

				// 离屏canvas大图位置
				const drawW1 = (this.offCtx.canvas.width / 4.4).toFixed(2);
				const drawh1 = (this.offCtx.canvas.height / 4.4).toFixed(2);
				const transX1 = (this.canvasStyle.width - drawW1) / 2;
				const transY1 = ((this.canvasStyle.height - drawh) / 2) * 1;

				// canvasDom绘制离屏Canvas
				const img1 = await this.getsubmitUrl(
					preview,
					preview1,
					this.canvasImg,
					transX,
					transY,
					drawW,
					drawh
				);
				const img2 = await this.getsubmitUrl(
					preview,
					preview1,
					this.canvasImg1,
					transX1,
					transY1,
					drawW1,
					drawh1
				);
				this.$emit('canvasFun')
				return [img1.canvasUrl, img2.canvasUrl, img1.offcanvasUrl];
			} catch (error) {
				this.$emit('canvasFun')
				console.log('getSwiperImg', error)
			}
		

		},

		// 收起键盘出发绘制事件
		async getsubmitUrl(
			preview = [],
			preview1 = [],
			canvasImg,
			transX,
			transY,
			drawW,
			drawh
		) {
			try {
				const ctx = this.ctx;
				// 清除离屏绘制内容
				this.offCtx.clearRect(
					0,
					0,
					this.offCtx.canvas.width,
					this.offCtx.canvas.height
				);
				// 清除canvas绘制内容
				ctx.save();
				ctx.clearRect(0, 0, this.canvasStyle.width, this.canvasStyle.height);
				ctx.drawImage(
					canvasImg,
					0,
					0,
					this.canvasStyle.width,
					this.canvasStyle.height
				);
				ctx.restore();
				// canvas换行处理

				this.offCtx.fillStyle = this.textColorImgs;
				const lineH = 110 + 36; //居中效果
				const dbLineH = 70 + 36;
				const dbLine1H = 170 + 36;
				const regex = /[\n\r]+/;
				const result = preview.every((item, index) => regex.test(item) || item == " ");
				const result1 = preview1.every((item, index) => regex.test(item) || item == " ");
				this.drawOffText(preview, !result1 ? dbLineH : lineH);
				this.drawOffText(preview1, !result ? dbLine1H : lineH);

				const { offcanvasUrl, offimg } = await this.domDrawOffCanvas();
				const canvasUrl = await this.drawCanvasImage(
					transX,
					transY,
					drawW,
					drawh,
					offimg
				);
				return { canvasUrl, offcanvasUrl };
			} catch (error) {
				console.log(error, 'getsubmitUrl')
			}
		},

		swiperChange(e) {
			let currentTimeStamp = new Date().getTime();
			if (currentTimeStamp - this.swiperChangeTimeStamp <= 500) {
				this.swiperChangeTimeStamp = currentTimeStamp;
				return false;
			} else {
				this.swiperChangeTimeStamp = currentTimeStamp;
			}
			this.currentIndex = e.detail.current;
		},

		async initCanvas(isGetCtx = false) {
			try {
				if (isGetCtx) {
					await this.getCtx();
				}
				// //获取Canvas背景tu
				this.canvasImg = await this.imgeOnload(this.previewImg[0]);
				this.canvasImg1 = await this.imgeOnload(this.previewImg[1]);
				this.previewSwiperImg = [this.canvasImg, this.canvasImg1];
				await this.loadColorImg();
			} catch (error) {
				console.log(error, "initCanvas");
			}
		},
		async loadColorImg() {
			try {
				this.textBg = await this.imgeOnload(
					this.textBgUrl + "?v=" + new Date().getTime()
				);
				if (this.textBg) {
					this.textColorImgs = this.offCtx.createPattern(this.textBg, "repeat");
					if (!this.textColorImgs) {
						this.textColorImgs = "#e7d099";
					}
				} else {
					this.textColorImgs = "#e7d099";
				}
			} catch (e) {
				this.textColorImgs = "#e7d099";
				console.log(e, "loadColorImg");
			}
		},
		uploadImg(w, h, canvas, dpr = 1) {
			return new Promise((resolve, reject) => {
				const that = this;
				uni.canvasToTempFilePath({
					canvas: canvas,
					quality: 1,
					destWidth: w * dpr,
					destHeight: h * dpr,
					async success(res) {
						resolve(res.tempFilePath);
					},
					fail(err) {
						reject("");
					},
				});
			});
		},

		imgeOnload(src) {
			return new Promise((resolve, reject) => {
				let img = this.offCanvas.createImage();
				img.src = src;
				img.onload = (e) => {
					resolve(img);
				};
				img.onerror = (e) => {
					reject(null);
				};
			});
		},
		getCtx() {
			return new Promise(async (resolve) => {
				// uni.createSelectorQuery()
				this.createSelectorQuery()
					.select("#canvas") // 在 WXML 中填入的 id
					.fields({
						node: true,
						size: true,
					})
					.exec((res) => {
						// 初始化离屏canvas
						this.offCanvas = uni.createOffscreenCanvas({
							type: "2d",
							width: 1000,
							height: 250,
						});
						// 获取 context。注意这里必须要与创建时的 type 一致
						this.offCtx = this.offCanvas.getContext("2d");
						const style = res[0];
						// Canvas 对象
						const canvas = res[0].node;

						// Canvas 画布的实际绘制宽高
						const renderWidth = style.width;
						const renderHeight = style.height;
						// Canvas 绘制上下文
						this.ctx = canvas.getContext("2d");
						this.canvas = canvas;
						this.canvasStyle = style;
						// 初始化画布大小
						const dpr = wx.getWindowInfo().pixelRatio;

						this.dpr = dpr;
						this.canvas.width = renderWidth * dpr;
						this.canvas.height = renderHeight * dpr;
						this.ctx.scale(dpr, dpr);
						resolve();
					});
			});
		},

		radiansToDegrees(radians) {
			const degreesPerRadian = 180 / Math.PI;
			return radians * degreesPerRadian;
		},
		// 导出离屏canvas
		async domDrawOffCanvas() {
			const offcanvasUrl = await this.uploadImg(
				this.offCtx.canvas.width,
				this.offCtx.canvas.height,
				this.offCanvas,
				2
			);
			const offimg = await this.imgeOnload(offcanvasUrl);
			return { offcanvasUrl, offimg };
		},

		// 将离屏canvas绘制到canvasDom中
		async drawCanvasImage(transX, transY, drawW, drawh, offimg) {
			this.ctx.drawImage(offimg, transX, transY, drawW, drawh);
			//将canvasDom导出
			const canvasUrl = await this.uploadImg(
				this.ctx.canvas.width,
				this.ctx.canvas.height,
				this.canvas,
				this.dpr
			);
			return canvasUrl;
		},

		drawOffText(lsit, y) {
			const textEN = /[a-zA-Z/]+/;
			const textNumber = /[0-9/]+/;
			const textZH = /[\u4e00-\u9fa5]/;
			const zhTextSymbol = /[“”，。、！；‘’：]/;
			const enTextSymbol = /[""'', .!;’:%]/;
			const symbolText = ["＆", "□", "☆", "♡"];
			const regex = /[\n\r]+/;
			const canvasWdith = this.offCtx.canvas.width / 2

			try {
				let totalTextWidth = 0;
				let xWidth = 0;
				let textWidth = 0;
				// 计算所有文本的总宽度
				for (let i = 0; i < lsit.length; i++) {
					const item = lsit[i];
					if (regex.test(item)) {
						textWidth = 0
					} else if (symbolText.includes(item)) {
						ICONfONT.forEach((el) => {
							if (el.t === item) {
								// 将字体单位的宽度转换为像素
								textWidth = (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
					} else if (
						textNumber.test(item) ||
						textZH.test(item) ||
						zhTextSymbol.test(item)
					) {
						ZHText.forEach((el) => {
							if (el.t === item) {
								// 将字体单位的宽度转换为像素
								textWidth = (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
					} else if (textEN.test(item) || enTextSymbol.test(item)) {
						ENText.forEach((el) => {
							if (el.t === item) {
								// 将字体单位的宽度转换为像素
								textWidth = (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
					}
					totalTextWidth += textWidth;
				}
				let x = (this.offCtx.canvas.width - totalTextWidth) / 2; // 计算起始绘制位置以使文本居中
				this.drawTextFun(x, lsit, y);
			} catch (error) {
				console.log(error, "drawOffText");
			}
		},
		drawTextFun(x, list, y, radius = 70) {
			const textEN = /[a-zA-Z/]+/;
			const textNumber = /[0-9/]+/;
			const textZH = /[\u4e00-\u9fa5]/;
			const textSpace = /\s/;
			const zhTextSymbol = /[“”，。、！；‘’：]/;
			const enTextSymbol = /[""'', .!;’:%]/;
			const symbolText = ["＆", "□", "☆", "♡"];
			const regex = /[\n\r]+/;
			const ctx = this.offCtx;

			try {
				// 计算所有文本的总宽度
				let totalTextWidth = 0;
				for (let i = 0; i < list.length; i++) {
					const item = list[i];
					if (regex.test(item)) {
						totalTextWidth += 0;
					} else if (symbolText.includes(item)) {
						ICONfONT.forEach((el) => {
							if (el.t === item) {
								totalTextWidth += (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
					} else if (
						textNumber.test(item) ||
						textZH.test(item) ||
						zhTextSymbol.test(item)
					) {
						ZHText.forEach((el) => {
							if (el.t === item) {
								totalTextWidth += (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
					} else if (textEN.test(item) || enTextSymbol.test(item)) {
						ENText.forEach((el) => {
							if (el.t === item) {
								totalTextWidth += (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
					}
				}

				// 计算起始绘制位置以使文本居中
				let startX = x;

				// 绘制文本
				let currentX = startX;
				for (let i = 0; i < list.length; i++) {
					const item = list[i];
					let textWidth = 0;

					if (regex.test(item)) {
						textWidth = 0;
					} else if (symbolText.includes(item)) {
						ICONfONT.forEach((el) => {
							if (el.t === item) {
								// 将字体单位的宽度转换为像素
								textWidth = (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
						ctx.font = `${this.fontSizePt}px Dancing-icon`;
					} else if (textSpace.test(item)) {
						// 空格宽度->英文空格宽度
						textWidth = (this.fontSizePt / this.fontCHwidth) * 259;
						ctx.font = `${this.fontSizePt}px Dancing-One`;
					} else if (
						textZH.test(item) ||
						zhTextSymbol.test(item) ||
						textNumber.test(item)
					) {
						ZHText.forEach((el) => {
							if (el.t === item) {
								// 将字体单位的宽度转换为像素
								textWidth = (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
						ctx.font = `${this.fontSizePt}px Dancing-Xt`;
					} else if (textEN.test(item) || enTextSymbol.test(item)) {
						ENText.forEach((el) => {
							if (el.t === item) {
								// 将字体单位的宽度转换为像素
								textWidth = (this.fontSizePt / this.fontCHwidth) * el.w;
							}
						});
						ctx.font = `${this.fontSizePt}px Dancing-One`;
					}

					// 计算字符的中心X坐标
					const centerX = currentX + textWidth / 2;

					// 计算Y轴偏移量（使用抛物线公式）
					const a = -1 / (radius * radius); // 控制曲线的开口大小
					const offsetY = a * Math.pow(centerX - (startX + totalTextWidth / 2), 2);

					// 确保第一个和最后一个字符在同一条直线上
					const boundedOffsetY = offsetY;
					// 绘制字符
					ctx.fillText(item, currentX, y + boundedOffsetY);

					// 更新下一个字符的X坐标
					currentX += Number(textWidth.toFixed(2));
				}
			} catch (error) {
				console.log(error, "drawTextFun");
			}
		},
	},
};
</script>

<style lang="less" scoped>
.c2bCanvas {
	// height: 652rpx;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;

	.icon {
		height: 16rpx;
		width: 100%;
	}

	.img_box {
		height: 572rpx;
		width: 572rpx;
	}

	.swiper-dots {
		width: 100%;
		height: 16rpx;
		display: flex;
		flex-direction: row;
		justify-content: center;
		align-items: center;
		font-size: 0;
	}

	.swiper-dots-item {
		position: relative;
		width: 36rpx;
		height: 16rpx;
		padding: 0;
		margin: 0 18rpx;
		flex-shrink: 0;
	}

	.swiper_box {
		width: 100%;
		height: 100%;
	}

	.slide-image {
		width: 100%;
		height: 100%;
	}

	.img-container {
		height: 572rpx;
		width: 572rpx;
		position: absolute;
		left: -9999rpx;
		// left: 0;

		.goodsLettering-canvas {
			width: 100%;
			height: 100%;
		}
	}
}
</style>